//
//  Problem1769.swift
//  TestProject
//
//  Created by 毕武侠 on 2021/5/4.
//  Copyright © 2021 zhulong. All rights reserved.
//

import UIKit

/*
 1769. 移动所有球到每个盒子所需的最小操作数
 有 n 个盒子。给你一个长度为 n 的二进制字符串 boxes ，其中 boxes[i] 的值为 '0' 表示第 i 个盒子是 空 的，而 boxes[i] 的值为 '1' 表示盒子里有 一个 小球。
 在一步操作中，你可以将 一个 小球从某个盒子移动到一个与之相邻的盒子中。第 i 个盒子和第 j 个盒子相邻需满足 abs(i - j) == 1 。注意，操作执行后，某些盒子中可能会存在不止一个小球。
 返回一个长度为 n 的数组 answer ，其中 answer[i] 是将所有小球移动到第 i 个盒子所需的 最小 操作数。
 每个 answer[i] 都需要根据盒子的 初始状态 进行计算。


 示例 1：
     输入：boxes = "110"
     输出：[1,1,3]
     解释：每个盒子对应的最小操作数如下：
     1) 第 1 个盒子：将一个小球从第 2 个盒子移动到第 1 个盒子，需要 1 步操作。
     2) 第 2 个盒子：将一个小球从第 1 个盒子移动到第 2 个盒子，需要 1 步操作。
     3) 第 3 个盒子：将一个小球从第 1 个盒子移动到第 3 个盒子，需要 2 步操作。将一个小球从第 2 个盒子移动到第 3 个盒子，需要 1 步操作。共计 3 步操作。
 示例 2：
     输入：boxes = "001011"
     输出：[11,8,5,4,3,4]
 提示：
     n == boxes.length
     1 <= n <= 2000
     boxes[i] 为 '0' 或 '1'
 */
@objcMembers class Problem1769: NSObject {
    func solution() {
        print(minOperationsPoint("110"))
        print(minOperationsPoint("001011"))
    }
    
    /*
     题意：取一点i，然后求出其他点到这个点的距离
     
     方法一：
     暴力破解
     */
    func minOperations(_ boxes: String) -> [Int] {
        // 1: 创建一个数组，记录所有不是‘0’的位置
        var qList:[Int] = []
        for (i,box) in boxes.enumerated() {
            if box != "0" {
                qList.append(i)
            }
        }
        
        var result:[Int] = []
        for i in 0..<boxes.count {
            var value = 0
            for q in qList {
                value += abs(q - i)
            }
            result.append(value)
        }
        
        return result
    }
    
    /*
     方法二：
     假设我们知道i点，左边有m个位置有小球，右边有n个位置有小球，那么result[i] = 左边m个小球移动的次数+右边n个小球移动的次数
     那么我们求i+1时，那么就是左边的m个小球移动的次数都要+1, 右边的需要-1，result[i+1] = result[i] + m - n
     */
    
    func minOperationsPoint(_ boxes: String) -> [Int] {
        // 1: 求出0位置，左边和右边的个数
        var left = 0
        var right = 0
        var all = 0
        for (i, box) in boxes.enumerated() {
            if box != "0" {
                all += i + 1        // +1的目的：创建一个-1的位置
                right += 1
            }
        }
        
        var result:[Int] = []
        for box in boxes {
            all += left - right
            result.append(all)
            if box != "0" {
                right -= 1
                left += 1
            }
        }
        
        return result
    }
}
